// 请详细说var，let，const三种声明变量之间的具体差别

/**
 * 1. 变量提升
 * var定义的变量有变量提升的效果，而let、const没有
 */


/** 
 * 2. 变量重复声明
 * 在同一作用域下，var可以重复声明相同的变量，而let、const每个变量只能声明一次
 */

{
  var a = 1
  var a = 2 // 不会报错

  let b = 1
  let b = 2 // 会报错

  const c = 1
  const c = 2 // 会报错
}

/**
 * 3. 变量的声明和赋值同时进行
 * var、let可以先声明变量在对变量进行赋值，而const只能声明变量的同时对其进行赋值
 */

{
  var a
  a = 1

  let b
  b = 2

  const c
  c = 3 // 报错

  const d = 4 // 正确
}

/**
 * 4. 值不可更改性
 * var、let可以重新对变量进行赋值，
 * 而const是常量，不能重新赋值，这里的常量指的是不可更改，不代表const定义的变量是不变的
 */
{
  var a = 1
  a = 2

  let b = 1
  b = 2

  const c = 1
  c = 2 // 报错，const定义的变量不能再次赋值

  const d = {}
  d.name = '1' // 这是正确的，对于引用类型的值，变量d指向的地址是没有变化的，只是地址指向的空间内值发生变化，并不算再次赋值
}

/**
 * 5. 块级作用域
 * var定义的变量，没有块级作用域，而let、const定义的变量有块级作用域
 * 块级作用域外没有办法访问块级作用域内的变量
 */
{
  {
    var a = 1
    let b = 1
    const c = 1
  }
  console.log(a) // log 1
  console.log(b) // 报错，无法访问
  console.log(c) // 报错，无法访问
}

